package com.company.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description: 手写自旋锁案例
 * @author: ruoan
 * @date: 2020/12/9 12:48
 */

@Slf4j
class Resource {
    private AtomicReference<Thread> atomicReference = new AtomicReference<>();


    /**
     * 枷锁
     */
    public void lock() {
        Thread thread = Thread.currentThread();


        // 没有加上锁就自旋
        while (!atomicReference.compareAndSet(null, thread)) {

        }

        log.info(Thread.currentThread().getName()+"枷锁完毕");

    }


    /**
     * 解锁
     */
    public void unlock() {
        Thread thread = Thread.currentThread();


        atomicReference.compareAndSet(thread, null);
        log.info(Thread.currentThread().getName()+"解锁完毕");


    }

}

@Slf4j
public class SpinLockDemo {

    public static void main(String[] args) {

        Resource resource = new Resource();
        new Thread(() -> {
            resource.lock();
            try {
                log.info(Thread.currentThread().getName()+"开始干活。。。。");
                try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
                log.info(Thread.currentThread().getName()+"结束干活。。。。");
            } finally {
                resource.unlock();
            }

        },"t1").start();

        new Thread(() -> {
            resource.lock();
            try {
                log.info(Thread.currentThread().getName()+"开始干活。。。。");
                try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
                log.info(Thread.currentThread().getName()+"结束干活。。。。");
            } finally {
                resource.unlock();
            }

        },"t2").start();



    }
}
